<template>
  <div class="execution-listener">
    <div class="listener-header">
      <span>执行监听器列表</span>
      <a-button type="primary" size="small" @click="handleAddListener">
        <template #icon><plus-outlined /></template>
        添加
      </a-button>
    </div>
    <a-table
      :columns="columns"
      :data-source="listeners"
      :pagination="false"
      size="small"
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'action'">
          <a-space>
            <a-button type="link" size="small" @click="handleEditListener(record)">编辑</a-button>
            <a-button type="link" size="small" danger @click="handleDeleteListener(record)">删除</a-button>
          </a-space>
        </template>
      </template>
    </a-table>

    <a-modal
      v-model:open="editPanelVisible"
      title="编辑执行监听器"
      :confirm-loading="loading"
      @ok="handleConfirm"
      @cancel="handleCancel"
    >
      <execution-listener-form
        ref="formRef"
        v-model:listener="listenerObject"
      />
    </a-modal>
  </div>
</template>

<script setup>
import { computed, onUnmounted, ref, watch } from "vue"
import { PlusOutlined } from '@ant-design/icons-vue'
import emitter from '/@/event/mitt'
import { useBpmnModeler, useBpmnSelectedElem } from '/@/config/app.hooks'
import ExecutionListenerForm from './ExecutionListenerForm.vue'

const bpmnSelectedElem = useBpmnSelectedElem()
const bpmnModeler = useBpmnModeler()

const loading = ref(false)
const formRef = ref()
const listeners = ref([])
const editPanelVisible = ref(false)
const listenerObject = ref()

const columns = [
  {
    title: '事件类型',
    dataIndex: 'event',
    key: 'event',
    width: 100
  },
  {
    title: '监听器类型',
    dataIndex: 'type',
    key: 'type',
    width: 120
  },
  {
    title: '值',
    dataIndex: 'value',
    key: 'value',
    ellipsis: true
  },
  {
    title: '操作',
    key: 'action',
    width: 120,
    fixed: 'right'
  }
]

const updateListeners = () => {
  const selectedElem = bpmnSelectedElem.value
  if (!selectedElem) {
    return
  }
  const bo = selectedElem.businessObject
  const extensionElements = bo.get('extensionElements')
  if (extensionElements) {
    const values = extensionElements.values
    listeners.value = values
      .filter(v => v.$type === 'flowable:ExecutionListener')
      .map(v => ({
        id: v.id,
        event: v.event,
        type: v.class ? 'class' : v.expression ? 'expression' : 'delegateExpression',
        value: v.class || v.expression || v.delegateExpression
      }))
  } else {
    listeners.value = []
  }
}

watch(() => bpmnSelectedElem.value, () => {
  updateListeners()
}, { immediate: true })

function handleAddListener() {
  const modeling = bpmnModeler.value.get('modeling')
  const moddle = bpmnModeler.value.get('moddle')
  const selectedElem = bpmnSelectedElem.value
  if (!selectedElem) {
    return
  }
  const bo = selectedElem.businessObject
  const extensionElements = bo.get('extensionElements') || moddle.create('bpmn:ExtensionElements')
  const listener = moddle.create('flowable:ExecutionListener', {
    event: 'start',
    class: ''
  })
  extensionElements.values = [...(extensionElements.values || []), listener]
  modeling.updateProperties(selectedElem, {
    extensionElements
  })
  updateListeners()
}

function handleEditListener(record) {
  listenerObject.value = record
  editPanelVisible.value = true
}

function handleDeleteListener(record) {
  const modeling = bpmnModeler.value.get('modeling')
  const selectedElem = bpmnSelectedElem.value
  if (!selectedElem) {
    return
  }
  const bo = selectedElem.businessObject
  const extensionElements = bo.get('extensionElements')
  if (extensionElements) {
    extensionElements.values = extensionElements.values.filter(v => v.id !== record.id)
    modeling.updateProperties(selectedElem, {
      extensionElements
    })
    updateListeners()
  }
}
async function handleConfirm() {
  // loading.value = true
  try {
    await formRef.value.validate()


    const modeling = bpmnModeler.value.get('modeling')
  const moddle = bpmnModeler.value.get('moddle')
  const selectedElem = bpmnSelectedElem.value
  if (!selectedElem) {
    return
  }
  const bo = selectedElem.businessObject
  const extensionElements = bo.get('extensionElements') || moddle.create('bpmn:ExtensionElements')
  const listener = moddle.create('flowable:ExecutionListener', {
    event: 'start',
    class: listeners.value[0].value
  })
  extensionElements.values = [listener]
  modeling.updateProperties(selectedElem, {
    extensionElements
  })
  updateListeners()

    // 实现确认逻辑
  } catch (e) {
    console.error(e)
  } finally {
    // loading.value = false
    editPanelVisible.value = false
  }
}

function handleCancel() {
  editPanelVisible.value = false
}

function handleElementChanged(event) {
  updateListeners()
}

function handleSelectionChanged(event) {
  editPanelVisible.value = false
}

emitter.on('bpmnElementChanged', handleElementChanged)
onUnmounted(() => emitter.off('bpmnElementChanged', handleElementChanged))

emitter.on('bpmnSelectionChanged', handleSelectionChanged)
onUnmounted(() => emitter.off('bpmnSelectionChanged', handleSelectionChanged))
</script>

<style scoped>
.execution-listener {
  padding: 12px;
}

.listener-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
</style>
